#include <iostream>

#include <boost/typeof/typeof.hpp>
#include <boost/bind.hpp>

#define PRINT( x ) do { std::cout << #x": " << x << std::endl; } while ( false )

struct test_t
{
	int value;
	int getValue( void ) { return value; }
};

class tracer {
public:
	int value;
	tracer() {
		std::cout << "tracer::tracer()\n";
	}

	tracer(const tracer& other) {
		std::cout << "tracer::tracer(const tracer& other)\n";
	}

	tracer& operator=(const tracer& other) {
		std::cout <<
			"tracer& tracer::operator=(const tracer& other)\n";
		return *this;
	}

	~tracer() {
		std::cout << "tracer::~tracer()\n";
	}

	void print(const std::string& s) const {
		std::cout << s << '\n';
	}
};

int main( int argc, char *argv[] )
{
	struct test_t t;
	t.value = 10;

	PRINT( boost::bind( &test_t::value, t )() );
	PRINT( boost::bind( &test_t::getValue, t )() );

	// PRINT( boost::bind( std::max, 10, 20 )() );
	PRINT( boost::bind( std::max< int >, 10, 20 )() );
	PRINT( boost::bind( std::max< int >, _1, t.value )( 5 ) );
	PRINT( boost::bind( std::max< int >, _1, t.value )( 20 ) );

	PRINT( boost::bind( std::less<int>(), t.value, _1 )( 5 ) );
	PRINT( boost::bind( std::less<int>(), t.value, _1 )( 20 ) );

	// just for note: PRINT( (std::less<int>()( 10, 20 )) );


	std::cout << "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" << std::endl;

	tracer tr;
	tr.value = 10;
	PRINT( boost::bind( std::plus< int >(),
				5,
				boost::bind( &tracer::value, _1 ) )( tr ) );
	PRINT( boost::bind( &tracer::value, _1 )( tr ) );

	return 0;
}
